﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SS.HP.Model
{
    public class Cart
    {
        public Cart()
        {
            Discounts = new Dictionary<int, double>();
            Discounts.Add(1, 0.0);
            Discounts.Add(2, 0.05);
            Discounts.Add(3, 0.1);
            Discounts.Add(4, 0.2);
            Discounts.Add(5, 0.25);
        }

        private Dictionary<int, double> Discounts { get; set; }

        private IList<Book> _books = new List<Book>();
        public IList<Book> Books
        {
            get { return _books; }
            set { _books = value; }
        }

        public void AddBook(Book book)
        {
            _books.Add(book);
            Recalculate();
        }

        public double Price
        {
            get { 
                return Books.Aggregate(0.0, (d, book) => d += book.DiscountedPrice);
            }
        }

        public IEnumerable<IGrouping<Series, Book>> BooksBySeries
        {
            get { return Books.GroupBy(book => book.Series); }
        }


        public IEnumerable<IGrouping<int, Book>> GetBooksInSeriesBySeriesIndex(Series series)
        {
            return Books.Where(x => x.Series.Name == series.Name).GroupBy(book => book.SeriesIndex);
        }

        public void Clear()
        {
            _books.Clear();
            Recalculate();
        }

        private void Recalculate()
        {
            var pricedBooks = new List<Book>();
            var books = _books.Select(x => x.DeepClone());
            foreach (var series in Books.Select(x=>x.Series).Distinct().ToArray())
            {
                SetPrices(series, Books, pricedBooks);                
            }
            Books = pricedBooks.Select(x=>x).ToList();
        }

        private IList<Book> SetPrices(Series series, IList<Book> books, IList<Book> pricedBooks)
        {
            var groupedBooks = books.Where(x => x.Series.Name == series.Name).GroupBy(book => book.SeriesIndex).ToList();

            if (!groupedBooks.Any())
            {
                return pricedBooks;
            }

            var discount = Discounts[groupedBooks.Count()];
            var firstInGroup = groupedBooks.Select(groupedBook => groupedBook.FirstOrDefault());

            foreach (var book in firstInGroup)
            {
                book.DiscountedPrice = (1 - discount)*book.RecommendedRetailPrice;
                books.Remove(book);
                pricedBooks.Add(book);
            }

            if (books.Count > 0)
            {
                SetPrices(series, books, pricedBooks);
            }

            return pricedBooks;
        }

    }
}
